package cMiddleware

import (
	"net/http"
	"reflect"
	"sync"

	"github.com/gin-gonic/gin"
)

type MiddlewareContainer struct {
	lock         sync.RWMutex
	instances    map[string]any
	errorHandler func(ctx *gin.Context, err error)
}

func (i *MiddlewareContainer) Save(instance any) bool {
	i.lock.Lock()
	defer i.lock.Unlock()

	app, name := instance.(MiddlewareInterface).MiddlewareName()
	index := app + "." + name
	i.instances[index] = instance

	return true
}

func (i *MiddlewareContainer) Get(name string) any {
	i.lock.RLock()
	defer i.lock.RUnlock()

	return i.instances[name]
}

func (i *MiddlewareContainer) Remove(name string) bool {
	i.lock.Lock()
	defer i.lock.Unlock()

	delete(i.instances, name)

	return true
}

func (i *MiddlewareContainer) Is(instance any) bool {
	return reflect.TypeOf(instance).Implements(reflect.TypeOf((*MiddlewareInterface)(nil)).Elem())
}

func (i *MiddlewareContainer) Range(f func(instance any)) {
	i.lock.RLock()
	defer i.lock.RUnlock()

	for _, item := range i.instances {
		f(item)
	}
}

func (i *MiddlewareContainer) SetErrorHandler(f func(ctx *gin.Context, err error)) {
	i.errorHandler = f
}

var container = &MiddlewareContainer{
	lock:      sync.RWMutex{},
	instances: make(map[string]any),
	errorHandler: func(ctx *gin.Context, err error) {
		ctx.String(http.StatusInternalServerError, "%s", err)
	},
}
